import { _decorator, Component, Material, Node, renderer, Sprite, tween, Tween, UIOpacity, UITransform, v4 } from 'cc';
import { BasicUI } from '../../Init/Basic/BasicUI';
import { UISystem } from '../../Init/SystemUI/UISystem';
import { UIEnum } from '../../Init/SystemUI/UIEnum';
import EventManager from '../../Init/Managers/EventManager';
import { EventTypes } from '../../Init/Managers/EventTypes';
import { Label } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('LoadingUI')
export class LoadingUI extends BasicUI {
    enterCb = null;
    exitCb = null;

    @property(Label)
    tip: Label = null;

    protected onLoad(): void {
        super.onLoad();
        EventManager.on(EventTypes.UIEvents.ShowLoadingExitAnim, this.onShowLoadingExitAnim, this);
        EventManager.on(EventTypes.UIEvents.ShowLoadingMsg, this.onShowLoadingMsg, this);
        this.initAnim();
    }

    protected onEnable(): void {
        this.tip.string = '努力加载中...';
        this.showAnimEnter();
    }

    protected onDisable(): void {
        this.resetAnim();
    }

    protected update(dt: number): void {
        this.updateAnim(dt);
    }

    public show(d: { enterCb?: Function, exitCb?: Function, msg?: string }): void {
        super.show();
        if (d) {
            this.enterCb = d.enterCb;
            this.exitCb = d.exitCb;
            if (d.msg) {
                this.tip.string = d.msg;
            }
        }
    }

    public hide(d?: any): void {
        super.hide(d);
        this.enterCb = null;
        this.exitCb = null;
    }

    private onShowLoadingExitAnim() {
        if (!this.node.activeInHierarchy) return;
        // 退出动画
        this.showAnimExit();
    }

    private onShowLoadingMsg(msg: string) {
        if (!this.node.activeInHierarchy) return;
        this.tip.string = msg;
        console.log('# loadingTip: ' + msg);
    }

    //#region --- 动画
    @property(Sprite)
    maskSp: Sprite = null;
    @property(Node)
    centerNode: Node = null;
    centerOpacity: UIOpacity = null;
    tipOpacity: UIOpacity = null;

    maskMat: Material = null;
    pass: renderer.Pass = null;
    paramName = 'maskSize';
    handle = 0;
    maskParam = v4(0, 0, 0, 0);

    animTime = 1.4;
    animData = { r: 1, s: 1, o: 1, };
    isEnterFinished = false;
    isExitFinished = false;

    initAnim() {

        this.maskMat = this.maskSp.customMaterial;
        this.pass = this.maskMat.passes[0];
        this.handle = this.pass.getHandle(this.paramName);

        const ctsize = this.maskSp.node.getComponent(UITransform).contentSize;
        this.maskParam.set(0, 0.03, ctsize.width, ctsize.height);

        this.centerOpacity = this.centerNode.getComponent(UIOpacity);
        this.tipOpacity = this.tip.node.getComponent(UIOpacity);
    }
    // 入场动画
    showAnimEnter() {
        Tween.stopAllByTarget(this.animData);

        this.animData.r = 1;
        this.maskParam.x = this.animData.r;
        this.setMatData();

        this.isEnterFinished = false;
        // mask 1->0
        tween(this.animData).
            to(this.animTime * 0.5, { r: 0 }, { easing: 'sineOut' }).
            start();

        // 缩放
        this.animData.s = 0;
        this.centerNode.setScale(this.animData.s, this.animData.s, 1);
        tween(this.animData).delay(this.animTime * 0.2).
            to(this.animTime * 0.5, { s: 1 }, { easing: 'backOut' }).
            call(() => {
                this.isEnterFinished = true;
                this.enterCb && this.enterCb();
            }).start();

        // 透明度
        this.centerOpacity.opacity = 0;
        this.tipOpacity.opacity = 0;
        tween(this.animData).delay(this.animTime * 0.2).
            to(this.animTime * 0.2, { o: 1 }).start();
    }
    // 退出动画
    showAnimExit() {
        Tween.stopAllByTarget(this.animData);
        this.animData.r = 0;
        this.maskParam.x = this.animData.r;
        this.setMatData();

        this.isExitFinished = false;
        // mask 0->1
        tween(this.animData).
            to(this.animTime * 0.5, { r: 1 }, { easing: 'sineOut' }).
            call(() => {
                this.isExitFinished = true;
                this.exitCb && this.exitCb();
                this.onAnimFinished();
            }).
            start();
        // 缩放 透明度   
        this.animData.s = 1;
        this.centerNode.setScale(this.animData.s, this.animData.s, 1);
        tween(this.animData).
            to(this.animTime * 0.1, { s: 1.2 }, { easing: 'sineOut' }).
            to(this.animTime * 0.2, { s: 0, o: 0 }, { easing: 'sineIn' }).
            start();
    }

    onAnimFinished() {
        UISystem.hideUI(UIEnum.LoadingUI);
    }

    resetAnim() {
        Tween.stopAllByTarget(this.animData);
        this.isEnterFinished = false;
        this.isExitFinished = false;
    }

    updateAnim(dt) {
        if (this.isEnterFinished && this.isExitFinished) return;
        this.maskParam.x = this.animData.r;
        this.setMatData();

        this.centerNode.setScale(this.animData.s, this.animData.s, 1);
        this.centerOpacity.opacity = this.animData.o * 255;
        this.tipOpacity.opacity = this.animData.o * 255;
    }

    setMatData() {
        this.pass.setUniform(this.handle, this.maskParam);
    }
    //#endregion


}

